package com.cnap.multiclouldmgmt.controller;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import com.cnap.multiclouldmgmt.model.CommonResult;
import com.cnap.multiclouldmgmt.model.enums.CloudVendorsEnum;
import com.cnap.multiclouldmgmt.model.gpu.MicroSvcGpuInfoModel;
import com.cnap.multiclouldmgmt.model.gpu.NodeQueryModel;
import com.cnap.multiclouldmgmt.model.gpu.SvcQueryModel;
import com.cnap.multiclouldmgmt.model.vm.*;
import com.cnap.multiclouldmgmt.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

/**
 * 对接其他后端相关系统
 * @author dyq
 */
@Api(tags ="对接其他后端相关系统")
@RequestMapping(path = "/cnap/multicloudmgmt/v1/be")
@RestController
@ResponseBody
public class BeController {

    private final static Logger LOGGER = LoggerFactory.getLogger(BeController.class);

    @Lazy
    @Autowired
    private VmResourceService vmResourceService;

    @Autowired
    private DockerHarborService dockerHarborService;

    @Autowired
    private MicroSvcInfoService microSvcInfoService;

    @Autowired
    private CacheService cacheService;


    /**
     * 开通云资源，完成以下内容
     * 1.申请开通虚机，调用其他接口
     * 2.完成安全组开通，
     * 3.完成k8s等组件安装
     * 4、完成调度平台组件安装
     * 如果svcId已经存在了，且errorMsg不为空，那就重试
     * 整个流程顺序执行，除非遇到问题会停下
     * @param vmCreateModel 基本信息
     * @return 结果
     */
    @ApiOperation(value = "6-1 创建服务需要的虚拟机资源",httpMethod = "POST",
            notes = "")
    @RequestMapping(path = "/createVmResource",method = RequestMethod.POST)
    public CommonResult<Void> createVmResource(@RequestBody VmCreateModel vmCreateModel) {

        try {

            vmResourceService.createVmResource(vmCreateModel);
            return CommonResult.successMsg("createVmResource succees");

        }catch (Exception e){

            LOGGER.error("BeController createVmResource error",e);

            return CommonResult.failed(e.getMessage());
        }
    }

    @ApiOperation(value = "6-2 查询显卡温度",httpMethod = "POST",
            notes = "")
    @RequestMapping(path = "/queryGpuHeat",method = RequestMethod.POST)
    public CommonResult<MicroSvcGpuInfoModel> queryGpuHeat(@RequestBody MicroSvcGpuInfoModel microSvcGpuInfoModel) {

        try {


            return CommonResult.success(microSvcInfoService.queryGpuHeat(microSvcGpuInfoModel));

        }catch (Exception e){

            LOGGER.error("BeController queryGpuHeat error",e);

            return CommonResult.failed(e.getMessage());
        }
    }

    @ApiOperation(value = "6-3 查询某个节点的某个指标的使用率",httpMethod = "POST",
            notes = "")
    @RequestMapping(path = "/queryNodeInfo",method = RequestMethod.POST)
    public CommonResult<NodeQueryModel> queryNodeInfo(@RequestBody NodeQueryModel nodeQueryModel) {

        try {

            LOGGER.warn("queryNodeInfo get data{}",JSONObject.toJSONString(nodeQueryModel));
            NodeQueryModel result = microSvcInfoService.queryResInfo(nodeQueryModel);
            LOGGER.warn("queryNodeInfor result = {}",JSONObject.toJSONString(nodeQueryModel));
            if (result.getQueryResult() < 0){
                return CommonResult.failed(HttpStatus.NOT_FOUND.value(),"node is lost controll");
            }

            return CommonResult.success(result);

        }catch (Exception e){

            LOGGER.error("BeController queryNodeInfo error",e);

            return CommonResult.failed(e.getMessage());
        }
    }

    @ApiOperation(value = "6-3 删除inditor",httpMethod = "POST",
            notes = "")
    @RequestMapping(path = "/delSvcHandler",method = RequestMethod.POST)
    public CommonResult<Void> delSvcHandler(@RequestBody DelSvcHandlerReqModel delSvcHandlerReqModel) {

        try {

            LOGGER.warn("delSvcHandler del svc_id={}",delSvcHandlerReqModel.getSvcId());
            microSvcInfoService.delIndictorHistory(delSvcHandlerReqModel.getSvcId());
            return CommonResult.successMsg("del svc indicator success");

        }catch (Exception e){

            LOGGER.error("BeController delSvcHandler error",e);

            return CommonResult.failed(e.getMessage());
        }
    }


    /**
     * v2.0中，还要删除服务对应的扩缩容策略，和
     * @param delNodeImageModel
     * @return
     */
    @ApiOperation(value = "5-2 删除服务之后，删除对应的节点上镜像",httpMethod = "POST",
            notes = "")
    @RequestMapping(path = "/delNodeImage",method = RequestMethod.POST)
    public CommonResult<Void> delNodeImage(@RequestBody DelNodeImageModel delNodeImageModel) {

        try {

            LOGGER.warn("/delNodeImage svcId={} clusters={} imageName={} svcname={}",delNodeImageModel.getSvcId(),
                    JSONObject.toJSONString(delNodeImageModel.getClusterInfos()),
                    delNodeImageModel.getImageName(),delNodeImageModel.getK8sServiceName());

            //删除时候，如果应用正在进行部署，那就停止，删除自己
            if (cacheService.getVmCreateTime(delNodeImageModel.getSvcId()) > 0){
                LOGGER.warn("/delNodeImage putStopVmCreateSvc svcId={}",delNodeImageModel.getSvcId());
                cacheService.putStopVmCreateSvc(delNodeImageModel.getSvcId());
            }

            if ((delNodeImageModel.getClusterInfos() == null)
                    ||(delNodeImageModel.getClusterInfos().isEmpty())){

                if (LOGGER.isInfoEnabled()){
                    LOGGER.info("########################");
                    LOGGER.info("delNodeImage imageName={} clusterName empty",
                            delNodeImageModel.getImageName());
                }

                return CommonResult.successMsg("delNodeImage succees");
            }

            for (DelNodeImageClusterInfoModel delNodeImageClusterInfoModel:delNodeImageModel.getClusterInfos()) {
                String clusterName = delNodeImageClusterInfoModel.getName();
                if (StringUtils.isNotEmpty(clusterName)) {

                    if (LOGGER.isInfoEnabled()) {
                        LOGGER.info("########################");
                        LOGGER.info("delNodeImage imageName={} clusterName={}",
                                delNodeImageModel.getImageName(), clusterName);
                    }

                    //删除镜像
                    dockerHarborService.delClusterImage(clusterName, delNodeImageModel.getImageName());

                    //删除微服务的扩缩容策略
                    try {
                        ScalingService scalingService = SpringUtil.getBean(ScalingService.class);
                        scalingService.deleteByClusterNameAndLabel(clusterName, delNodeImageModel.getSvcId());
                    }catch (Exception e){
                        LOGGER.error("del scaling policy fail clusterName={} svcId={}",
                                clusterName,delNodeImageModel.getSvcId(),e);
                    }

                    //把部署应用的node删除掉
                    //如果是master节点，就吧label去掉
                    microSvcInfoService.delMicroSvc(delNodeImageModel.getK8sServiceName(),clusterName,
                            delNodeImageModel.getSvcId());

                }
            }
            return CommonResult.successMsg("delNodeImage succees");

        }catch (Exception e){

            LOGGER.error("VmController delNodeImage error",e);

            return CommonResult.failed(e.getMessage());
        }
    }

    /**
     * 步骤一删除，删除信息，删除节点
     * 步骤二删除，删除信息，删除节点。
     * 步骤三删除，如果集群不存在，那就删除信息，删除节点
     * 如果集群存在，那就结束步骤，不对节点做操作
     * 步骤四删除，不做动作。
     * @param delNodeImageModel
     * @return
     */
    @ApiOperation(value = "5-3 删除服务之后，删除未结束的创建虚机的信息",httpMethod = "POST",
            notes = "")
    @RequestMapping(path = "/delSvcToVmCreate",method = RequestMethod.POST)
    public CommonResult<Void> delSvcToVmCreate(@RequestBody DelSvcToVmModel delNodeImageModel) {

        try {

            LOGGER.warn("/delSvcToVmCreate begin svcId={} type={}",delNodeImageModel.getSvcId(),
                    delNodeImageModel.getType());

            //删除时候，如果应用正在进行部署，那就停止，删除自己
            if (cacheService.getVmCreateTime(delNodeImageModel.getSvcId()) > 0){
                LOGGER.warn("delSvcToVmCreate putStopVmCreateSvc svcId={}",delNodeImageModel.getSvcId());
                cacheService.putStopVmCreateSvc(delNodeImageModel.getSvcId());
            }

            vmResourceService.delSvcToVmCreate(delNodeImageModel.getSvcId(),delNodeImageModel.getType());

            return CommonResult.successMsg("delNodeImage succees");

        }catch (Exception e){

            LOGGER.error("VmController delSvcToVmCreate error",e);

            return CommonResult.failed(e.getMessage());
        }
    }

}
